package com.icesoft.core.dao.listener;

import com.icesoft.core.dao.base.Model;
import com.icesoft.core.dao.criteria.QueryBuilder;
import com.icesoft.core.dao.suppose.HqlQuerySuppose;
import com.icesoft.core.dao.suppose.IDaoInterceptor;
import com.icesoft.core.dao.suppose.validation.UniqueCheck;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

@Component
@AllArgsConstructor
class UniqueCheckValidator implements IDaoInterceptor {

    private HqlQuerySuppose hqlQuerySuppose;

    @Override
    public void onCreate(Model model) {
        valid(model);
    }

    @Override
    public void onUpdate(Model model) {
        valid(model);
    }

    private void valid(Model model) {
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(model);
        Field[] fields = model.getClass().getDeclaredFields();
        for (Field field : fields) {
            UniqueCheck unique = field.getAnnotation(UniqueCheck.class);
            if (unique == null) {
                continue;
            }
            Object val = beanWrapper.getPropertyValue(field.getName());
            if (val == null) {
                continue;
            }
            QueryBuilder qb = QueryBuilder.get();
            if (model.getId() != null) {
                qb.andNe("id", model.getId());
            }
            qb.andEq(field.getName(), val);
            for (String name : unique.cascade()) {
                qb.andEq(name, beanWrapper.getPropertyValue(name));
            }
            if (hqlQuerySuppose.isExist(qb.from(model.getClass()))) {
                throw new IllegalArgumentException(unique.message());
            }
        }
    }
}  
